package cn.thr.ymcc.service.impl;

import cn.thr.ymcc.domain.Login;
import cn.thr.ymcc.dto.Logininfodto;
import cn.thr.ymcc.jwt.JwtUtils;
import cn.thr.ymcc.jwt.PayloadData;
import cn.thr.ymcc.jwt.RsaUtils;
import cn.thr.ymcc.mapper.LoginMapper;
import cn.thr.ymcc.result.JsonResult;
import cn.thr.ymcc.service.ILoginService;
import cn.thr.ymcc.util.AssertUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.security.PrivateKey;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 登录表 服务实现类
 * </p>
 *
 * @author thr
 * @since 2023-02-24
 */
@Service
public class LoginServiceImpl extends ServiceImpl<LoginMapper, Login> implements ILoginService {
    @Value("${jwt.rsa.pri}")
    private String pri;

    @Autowired
    private LoginMapper loginMapper;

    /**
     * 统一登录平台  前后端通用
     * 登录接口
     * @param logininfodto
     * @return
     */
    @Override
    public JsonResult accountLogininfo(Logininfodto logininfodto) {
        //1.根据用户名查数据 selent * from t_login where username =?
        //baseMapper 等同于LoginMapper   selectOne执行一条SQL  new QueryWrapper<查那一张表> 拿数据库的数据  eq 相当于where 用来最对比
        Login login = baseMapper.selectOne(new QueryWrapper<Login>()
                .eq("username", logininfodto.getUsername()));

        //2.校验查询的对象是否为空
        //AssertUtil 工具类  isTrue();封装了if判断
        AssertUtil.isTrue(login != null,"用户名不存在");

        //3.校验密码：加密规则是 BCryptPasswordEncoder() matches方法，第一个参数为明文！！！，第二个参数才是密文 ！！！  如果
        AssertUtil.isTrue(new BCryptPasswordEncoder().matches(logininfodto.getPassword(), login.getPassword()), "密码错误！");

        /**
         * 4.登录成功
         * 1)利用jwt工具类 私钥加密  ，将 login 对象作为载荷 生成JWt 字符串
         * 2)JWT 字符串和login 对象数据封装到HashMap 返回到前端
         */
        try {
            //放入载荷的东西
            PayloadData payloadData = new PayloadData();
            login.setPassword(null);
            payloadData.setLogin(login);
            //判断是不是管理员
            if(logininfodto.getType()== 0){
                //链表查询用户拥有的权限
                //通过t_role_permission   role_id 去查询 t_permission中间表的id  只需要中间表的sn
                //List<String> permissionsByRoleIds = roleMapper.getPermissionsByRoleIds(roles); //获取到自己角色的权限 取到sn
                //把权限加入进去
               // payloadData.setPermissions(new HashSet<>(permissionsByRoleIds));

                //菜单很特殊  链表查询
//                List<Menu> all = menuService.findAll();
//                payloadData.setMenus(p);

            }

            // 1 生成token
            PrivateKey privateKey = RsaUtils.getPrivateKey(JwtUtils.class.getClassLoader().getResource(pri).getFile());
            String token = JwtUtils.generateTokenExpireInMinutes(payloadData, privateKey, 720);
            //返回回去
            Map<String,Object> map = new HashMap<>();

            map.put("JwtToken",token);
            map.put("login",login);
            return JsonResult.me(map);
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.error("登陆失败");
        }
    }

    @Override
    public void loginRole(Long loginId,Long roleId) {
        loginMapper.loginRole(loginId,roleId);
    }

}
